<?php

namespace app\common\library;

use fast\Random;
use think\Hook;

class Acsign
{
    public function __construct(){
//        'https://prev.asign.cn'//测试环境
//        'https://oapi.asign.cn'//正式环境
//        $this->notifyUrl = 'https://oapi.asign.cn';
//        $this->publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALwxjHOCmoY9N5h+uhWYdmES4920yTvWUERtkz+ac8KZF2dVgC5QaWZhmEz/nw27Ln6AP90ZCMPi+iNF1m9mhNECAwEAAQ==';
//        $this->appId = '350236852';
//        $this->apiSecret = 'MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCDWmAn79iNG+5eyFmbufAH2ZaSuYTPTLbQ4UIFhZcbyqt3xQhzNMW8tTRZY1co31hPpDt13h9rB2VRgaSg2XRGhdGkAguttTHpEI11cut9K6hJA7lZ0ZrONi9yrcBI7D2zfjhIBcITJJy1QK/4WgUPzjNI4Pa1jHF7T7q5JcrbJkZ8fRmbfbfWn+k1t7ovnNryIuJuMadgm77yl8Zs6pvYeUiw1wgiQtiP/bn+0C9d8/Lxl0e0h0cCPbFvGPqNp+zgricmZCAgXkJ8p5kNF7wOhXEJrhL/zpQiQWmiTTkhA6jENPhWtpBoWqkmc7VQL7VrX6fH+TWxSKTjbptULrNZAgMBAAECggEAcgrRWVtAJKOPffNs+WuiHu6ncJRp3qG4R/qLG8g0vghkfwQupfe3hnO9E67QSchAIEVy6o8DsCUnrnBkwtKJxYEB1ud/xD2BK90XNFWmZ3K0FVCKaJU3Vrpsz6BTRfz2RRTdQIrfSUeMV0HmhjWCF4rrs+a9zDo3fNxoPb+2NDXyapGRTprCfLwXs42Lww/nb1k86/fLQmSOButbDflbOM9J0xoLWmddeJ0TLdS1R7libj/wCB3p2loDMLcr3asEnR3PA51OBLbxWhXXzWV1azBIRTja8BRgaalF0eudMI0vKrWByTpJ1xwFfm8DEsibTMZnZIImKrBKYPBkmRSyAQKBgQDOeLx325KhcKP3ccWhxDXorcskHFO5rErj8/N8pnrBbC7WuOOz5xUcbnilhAxrgMTF2GLJtTny2JjMaMCDySqBwOKGD+2F90wUA9ACy3sHEZhXdNYuoQLymN+PivctzizzJRkhndOiqv11rne2+uxVKoPl4GVjF5yRXXJP7e1pEQKBgQCi3KoHYAPGFRQOxv/do+mgJwFlJEvtMMxhpZIoJtedlcwiTiwYzgSKn2lrmv82I8XC1LMkI/z3MQ8syFGtOJu22lFuuihrCVtdKxU8AeGDS/ohvrvswKCeAAshEqsnU0vChoXDiyzO9ZzaFkwSMW8CEk/VgfZb/+rKCceBARvlyQKBgFjswy9UEEkbvGLcS2Qqn5VBFNbOpHi5bd/Tt7Cd+wzHTT0JkHhxNDR0l92hi7/ZS+ZyFcoOFZE0HEsdapzXzUjpDCb1QTWLluaf5bzuamRW/afdGEoo6p4VnWOzVFYUEGQAPFywHvBWeKdwpvrWA2eC0h/1j3UoPDSXbJ5kOPYhAoGAFsw46Oth29qbgi4NJyOI0qhjI5tfHYbVNV4OBZzaVe7gMnUq6xX7wMPr5+o8i4Gab1mC8i4vfRLbAvPPqyXfdks9VvisK7+VkIc1Y78HqG98RjkC6XNViIiNBkYsu0aHtmVKWEMlNJthJ44ze+B7n5icoFCfAeXjIgEYclCLbTECgYA33jaZU0DNJCfyqGa+J+UgRjWcFokv3pE6V6JXRW7lg2SlIODNaDegHREStw2LRhybaYj+ElRK3KttY6E3nEC7C64kywgqB5g2ZUULcp2axI6EvlcsjOr0YkkK6PTYElJ4mMVcirpEml+7ODienljN/6DK865x3D8T9dtoHhl+jg==';
//        $this->domian = 'https://oapi.asign.cn';

        //测试环境
        $this->notifyUrl = 'https://prev.asign.cn';
        $this->publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALwxjHOCmoY9N5h+uhWYdmES4920yTvWUERtkz+ac8KZF2dVgC5QaWZhmEz/nw27Ln6AP90ZCMPi+iNF1m9mhNECAwEAAQ==';
        $this->appId = '160172306';
        $this->apiSecret = 'MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC322at/vAJ70wsktNzKgmoMnM1D9wZdNQWyJsWprkise1F66AETbzA7Ax/OIIVwG8i6Yn52I6t4lzjJ7LNc9RpCE0Stneap1/DZkCYztlmwuk3BYP3QlVtDUFFv9G5OTXbzD63GiP31KcbL9+TRZxmp60OGFi5VOxVmp0+UNNnbEp8o7yrBFocGDXodQEAtETEfph9sdW6JU3r0W3sOTBmedp3HsYS7xvuTGC/69MqAFV269eZGeyoHqaxAOcnnwU4+7TQcTprsnmK5wK2oma2w8/lYCaESvwrphlOrF8FeBbuJTnue/+o0448rGy/tdbe4KzzVHIzJO95rtGm36+hAgMBAAECggEBAI1ISuIgCuMHgTirZ1OTFTKr+f3nfxIMxcHwS8UfPxsbMSLOyvsjpY12lq/Yg5YldwGUBtP4hsO2M/zWj77zaGGB4IAluUkdnygvVipWoZcm5kHCukLyNWUEj4kCuy2jefC6ReM8cjFKt1Lb+elYz7PO29v994gLa0To+DZfs+Q/cEvecCUZMyzuf2D6oV0qN8VUamkEbxVlLXgEAOOlTOjHLJyoqDw8Xr6xk3NcGjn7ptwR9uDoA+FSjRzKicGThNtDRvxP+uvtuPINFbwvUJRKfRaxT7GgGtzq5+MzgXASWfF012CqIM6I5Q5lrvS6X3qWCdHDGzbNI62d+QZw+XUCgYEA/sKITKz2ThKxLuVxIvBsPsVwiQ5r1jJZN2fRRlGvjOBogRjlFr6guppU244lrWejK4ja7jfj+HD5bAKFwuAhm5S0fNGbCow1q7A/Luta0r+DJQpJP0qC0ZUkViDs70z7TWQqXtfF5dHstXubdyjdFGlwcMeyf8lmG0WUBksJTUMCgYEAuMCDc6zRIejUkNkbvKMJzd5rUJHhniU++J/2IDbeUt3Zz+QfhYzcIMj3r/NMJoLZRfiIkVKJKyygOkNTrWKp72EbV/DkstmIHXb+BVRV0pV656LKNvE77QOI3q8TOJ6uPM3C/wzsZKwjMU8PMZHwjbBxVge6ygQ9hcow2kVib0sCgYEAhaD0bYOsDneviLHBDlqd7K8TwFBYMBpowa8rDn96XaK4Lj8oqy2CkV6ydBezm6lo5UT70Uhvw7k+m3EXSIjYGAuAQJiRgo7Y+B2ShsHc+f6Kg7tJgHFM/TIFxUewADWY+5c2wljb7RiX2PnlKjO9Ax/rYrzc3Dp/3H46jrJ9RpECgYEAok8/LRjeglPyq26Rl6AEtQB6d0YyWKWQNQ0TRinuGA8flCxuJP4jRgpI0COG+y5pg7ddA47nQy7pdUZA9UqA0PUW+KOByD6j/n7TnAsDewYn++hgjvRQGWHJlRlqYYvGt1Rtw3SvGaLBKEi0qG/2TgR9DX+s8l3XTvrbAGeEmxECgYAGHESs71b/hABcb9c7oS/QA7zbIFEkR4N2UObq+Oo/BHSHxWTpMx9oHTUwnF6KSEuiYWqOJudXok4YS3qk5Ng+jSQJeIK55NvpEkQ2f+2nLDAQfQIoVOko21WEkyHF18BNm51LNOz3fUXiC7TLZ8ohQ2B2R/TlIkJYDyg/cwPT2A==';
        $this->domian = 'https://prev.asign.cn';
    }

    /**
     * 个人实名认证网页版
     * @param $user
     * @return array
     */
    public function authPersonIdentifyUrl($user)
    {
        $this->url = '/auth/person/identifyUrl';
        $this->data = $user;
        return $this->request();
    }

    /**
     * 个人运营商三要素认证
     * @param $user
     * @return array
     */
    public function authPersonMobile3($user)
    {
        $this->url = '/auth/person/mobile3';
        $this->data = $user;
        return $this->request();
    }

    /**
     * 个人人脸活体认证
     * @param $user
     * @return array
     */
    public function authPersonFace($user)
    {
        $this->url = '/auth/person/face';
        $this->data = $user;
        return $this->request();
    }

    /**
     * 企业法人运营商三要素认证
     * @param $user
     * @return array
     */
    public function authCompanyMobile3($company)
    {
        $this->url = '/auth/company/mobile3';
        $this->data = $company;
        return $this->request();
    }

    /**
     * 重新发送认证验证码
     * @param $serialNo
     * @return array
     */
    public function authCaptchaResend($serialNo)
    {
        $this->url = '/auth/captcha/resend';
        $this->data = [
            'serialNo'   => $serialNo,
        ];
        return $this->request();
    }
    /**
     * 查询实名认证详细信息
     */
    public function getAuthRecordInfo($serialNo)
    {
        $this->url = '/auth/getAuthRecordInfo';
        $this->data = [
            'serialNo'   => $serialNo,
        ];
        return $this->request();
    }

    /**
     * 认证验证码校验
     * @param $serialNo
     * @param $captcha
     * @return array
     */
    public function authCaptchaVerify($serialNo,$captcha)
    {
        $this->url = '/auth/captcha/verify';
        $this->data = [
            'serialNo'   => $serialNo,
            'captcha'    => $captcha,
        ];
        return $this->request();
    }

    /***
     * 添加个人用户(V2)。
     *
     * @param $user
     * @return array
     */
    public function addPersonalUserV2($user){
        $this->url = '/v2/user/addPersonalUser';
        $this->data = $user;
        return $this->request();
    }

    /**
     * 添加企业用户(V2)。
     *
     */
    public function addEnterpriseUserV2($company){
        $this->url = '/v2/user/addEnterpriseUser';
        $this->data = $company;
        return $this->request();
    }

    /**
     * 获取用户信息。
     */
    public function getUser($account, $idcard=null, $creditCode=null){
        $this->url = '/user/getUser';
        if($account){
            $this->data["account"] = $account;
        }

        if($idcard){
            $this->data["idcard"] = $idcard;
        }

        if($creditCode){
            $this->data["creditCode"] = $creditCode;
        }

        return $this->request();
    }

    /**
     * 修改手机号。
     */
    public function modifyMobileByCode($account,$mobile,$code,$codeToken){
        $this->url = '/user/modifyMobileByCode';
        $this->data = [
            'account'   => $account,
            'mobile'    => $mobile,
            'code'      => $code,
            'codeToken' => $codeToken,
        ];
        return $this->request();
    }

    /**
     * @author: Neupres·lin
     * @name: sendCode
     * @description: 发送验证码（修改用户绑定手机号）
     * @param {*}String $account 用户唯一识别码
     * @return {*}
     */
    // $adduser = $this->ACsign->sendCode("13929792521");
    public function sendCode($account){
        $this->url = '/user/sendCode';
        $this->data = [
            'account'   => $account,
        ];
        return $this->request();
    }

    public function createSeal($file, $sealInfo){
        $this->url = '/user/createSeal';
        $this->data = $sealInfo;
        return $this->requestFile($file, "image");
    }

    /**
     * @author: Neupres·lin
     * @name: modifySeal
     * @description: 修改印章
     * @param {*}String $account 用户唯一识别码
     * @param {}MultipartFile $image 图片信息
     * @param {*}String $isDefault 是否默认签，0：否 1：是
     * @param {*}String $sealName 印章名称 (60个字符以内)
     * @param {*}String $sealNo 印章编号 (32个字符)
     * @param {}float $scaling 图片缩放百分比 (介于0~1之间的数字)
     * @return {*}
     */
    public function modifySeal($account,$image,$isDefault,$sealName,$sealNo,$scaling){
        $this->url = '/user/modifySeal';
        $this->data = [
            'account'   => $account,
            'image'     => $image,
            'isDefault' => $isDefault,
            'sealName'  => $sealName,
            'sealNo'    => $sealNo,
            'scaling'   => $scaling,
        ];
        return $this->request();
    }
    /**
     * @author: Neupres·lin
     * @name: removeSeal
     * @description: 删除印章
     * @param {*}String $account 用户唯一识别码
     * @param {*}String $sealNo 印章编号
     * @return {*}
     */
    public function removeSeal($account,$sealNo){
        $this->url = '/user/removeSeal';
        $this->data = [
            'account' => $account,
            'sealNo'  => $sealNo,
        ];
        return $this->request();
    }

    public function ocrIdentify($file,$side){
        $this->url = '/user/ocrIdentify';
        $this->data = [
            'side'  => $side,
        ];
        return $this->requestFile($file, "image");
    }

    /**
     * @author: Neupres·lin
     * @name: setDefaultSeal
     * @description: 设置默认章
     * @param {*}String $account 用户唯一识别码
     * @param {*}String $sealNo 印章编号如果为空，将把爱签系统生成的默认章重新设置为默认
     * @return {*}
     */
    public function setDefaultSeal($account,$sealNo){
        $this->url = '/user/setDefaultSeal';
        $this->data = [
            'account' => $account,
            'sealNo'  => $sealNo,
        ];
        return $this->request();
    }
    /**
     * @author: Neupres·lin
     * @name: getUserSeals
     * @description: 获取用户的印章列表
     * @param {*}String $account 唯一识别码
     * @return {*}
     */
    public function getUserSeals($account){
        $this->url = '/user/getUserSeals';
        $this->data = [
            'account' => $account,
        ];
        return $this->request();
    }
    /**
     * @author: Neupres·lin
     * @name: createLegalPersonSeal
     * @description: 创建法人章
     * @param {*}String $account 法人账号
     * @param {*}String $companyAccount 法人关联的企业账号
     * @return {*}
     */
    public function createLegalPersonSeal($account,$companyAccount){
        $this->url = '/user/createLegalPersonSeal';
        $this->data = [
            'account'        => $account,
            'companyAccount' => $companyAccount,
        ];
        return $this->request();
    }

    /**
     * 上传待签署文件。
     *
     */
    public function createContract($contractInput, $contractFiles) {
        $this->url = '/contract/createContract';
        $this->data = $contractInput;
        // 模板上传不需要文件
        return $this->requestFile($contractFiles, 'contractFiles');
    }

    /**
     * 去掉空值的key。
     *
     * @param $obj
     * @return array
     */
    public function filterEmpty($data) {
        $obj = $data;
        // 是数组
        if(is_array($obj)) {
            ksort($obj);
            foreach ($obj as $k => $v) {
                if(is_object($obj[$k]) || is_array($obj[$k])){
                    $obj[$k]= $this->filterEmpty($obj[$k]);
                }else {
                    if($v === null) {
                        unset($obj[$k]);
                    }
                }
            }
        }else {
            foreach ($obj as $k => $v) {
                if(is_object($obj->$k) || is_array($obj->$k)){
                    $obj->$k = $this->filterEmpty($obj->$k);
                }else if(!$v) {
                    unset($obj->$k);
                }
            }
        }

        return $obj;
    }

    /**
     * 去掉空值的key。
     *
     * @param $arr
     * @return array
     */
    public function filterEmptyArr($arr) {
//        foreach ($arr as $k => $v) {
//            if(!$v) {
//                array_filter($arr[$k]);
//            }
//        }
        // return array_filter($arr;
    }

    /***
     * 添加签署方。
     *
     * @param $data
     * @return array
     */
    public function addSigner($data){
        $this->url = '/contract/addSigner';
        $this->data = $data;
        return $this->request();
    }

    /**
     * @author: Neupres·lin
     * @name: getContractStatus
     * @description: 查询合同状态
     * @param {*}String $contractNo 合同编号
     * @return {*}
     */
    public function getContractStatus($contractNo){
        $this->url = '/contract/getContractStatus';
        $this->data = [
            'contractNo'       => $contractNo,
        ];
        return $this->request();
    }
    /**
     * @author: Neupres·lin
     * @name: getContract
     * @description: 查询合同信息
     * @param {*}String $contractNo 合同编号
     * @return {*}
     */
    public function getContract($contractNo){
        $this->url = '/contract/getContract';
        $this->data = [
            'contractNo'       => $contractNo,
        ];
        return $this->request();
    }
    /**
     * @author: Neupres·lin
     * @name: downloadContract
     * @description: 下载合同
     * @param {*}String $contractNo 合同编号
     * @param {}String $outfile 文件本地路径（下载的文件，写到本地）
     * @param {}int $downloadFileType 合同文件类型（多附件下载 1：pdf文件, 2：多个单张png文件（含pdf文件，单附件对应单张图片）, 3：分页png压缩文件 （含pdf文件）, 4：合同单张图片（不含pdf文件）, 5：所有的分页图片（不含pdf文件））
     * @return {*}
     */
    public function downloadContract($contractNo,$outfile,$downloadFileType){
        $this->url = '/contract/downloadContract';
        $this->data = [
            'contractNo'       => $contractNo,
            'outfile'          => $outfile,
            'downloadFileType' => $downloadFileType,
        ];
        return $this->request();
    }

    /**
     * 下载到本地仅供参考
     * @param $base64_image_content
     * @param $path
     * @return void
     */
    public function base64_image_content($base64_image_content,$path)
    {
        $pdf_decoded = base64_decode($base64_image_content);

        if (file_exists($path)){
            unlink($path);
        }
        $pdf = fopen( $path, 'w');
        fwrite($pdf, $pdf_decoded);
        fclose($pdf);
    }
    /**
     * @author: Neupres·lin
     * @name: uploadTemplate
     * @description: 上传模板
     * @param {*}String $templateName 模板名称
     * @param {*}String $templateNo 模板编号
     * @param {*}MultipartFile $templateFile 模板文件
     * @return {*}
     */
    public function uploadTemplate($templateName,$templateNo,$templateFile){
        $this->url = '/contract/uploadTemplate';
        $this->data = [
            'templateName' => $templateName,
            'templateNo'   => $templateNo,
            'templateFile' => $templateFile,
        ];
        return $this->request();
    }
    /**
     * @author: Neupres·lin
     * @name: downloadTemplate
     * @description: 下载模板
     * @param {*}String $templateNo 模板编号
     * @param {}String $outfile 文件本地路径（下载的文件，写到本地）
     * @return {*}
     */
    public function downloadTemplate($templateNo,$outfile){
        $this->url = '/contract/downloadTemplate';
        $this->data = [
            "templateNo" => $templateNo,
            "outfile" => $outfile,
        ];
        return $this->request();
    }
    /**
     * @author: Neupres·lin
     * @name: previewContract
     * @description: 预览合同
     * @param {*}String $contractNo 合同唯一编码 (40位之内)
     * @param {*}String $account 唯一识别码
     * @param {}int $isWrite 是否手写章（个人用户必传）1：是，0：否
     * @param {*}List{Object} $signStrategyList 在合同附件中签约策略
     * signStrategyList 参数说明 attachNo int 是 附件编号，合同上传的附件序号:1,2,3… locationMode String 是 定位方式，2-坐标签章（仅支持坐标） signPage int 是 签约页码:坐标签约必传 signX double 是 左上角为原点，离左边框的宽度与pdf当页宽度的比例（小数位2位）, 坐标签约必传 signY double 是 左上角为原点，离顶边框的高度与pdf当页高度的比例（小数位2位）, 坐标签约必传
     * @return {*}
     */
    public function previewContract($contractNo,$account,$isWrite=1){
        $this->url = '/contract/previewContract';
        $this->data = [
            [
                'contractNo'       => $contractNo,
                'account'          => $account,
                'isWrite'          => $isWrite,
                'signStrategyList' => [
                    // [
                    //     'attachNo'     => '',
                    //     'locationMode' => '',
                    //     'signPage'     => '',
                    //     'signX'        => '',
                    //     'signY'        => ''
                    // ]
                ]
            ]
        ];
        return $this->request();
    }
    /**
     * @author: Neupres·lin
     * @name: passSign
     * @description: 密码签署合同
     * @param {*}String $contractNo 合同唯一编码 (40位之内)
     * @param {*}String $account 唯一识别码
     * @param {*}String $signPwd 签署密码
     * @return {*}
     */
    public function passSign($contractNo,$account,$signPwd){
        $this->url = '/contract/passSign';
        $this->data = [
            'contractNo' => $contractNo,
            'account'    => $account,
            'signPwd'    => $signPwd,
        ];
        return $this->request();
    }
    /**
     * @author: Neupres·lin
     * @name: downloadWithCert
     * @description: 下载存证证书
     * @param {} $contractNo 合同编号（合同编号与存证编号不能同时为空）
     * @param {} $preserveNo 存证编号（合同编号与存证编号不能同时为空）
     * @param {} $outfile 文件本地路径（下载的文件，写到本地）
     * @return {*}
     */
    public function downloadWithCert($contractNo,$preserveNo,$outfile){
        $this->url = '/contract/downloadWithCert';
        $this->data = [
            'contractNo' => $contractNo,
            'preserveNo' => $preserveNo,
            'outfile'    => $outfile,
        ];
        return $this->request();
    }
    /**
     * @author: Neupres·lin
     * @name: saveEvidence
     * @description: 合同存证
     * @param {*}String $contractNo 合同编号
     * @return {*}
     */
    public function saveEvidence($contractNo){
        $this->url = '/contract/saveEvidence';
        $this->data = [
            'contractNo' => $contractNo,
        ];
        return $this->request();
    }

    /**
     * @author: Neupres·lin
     * @name: downloadByAttachName
     * @description: 下载合同（根据附件名）
     * @param {*}String $contractNo 合同编号
     * @param {*}List < String > $attachNames 附件名
     * @param {}String $outfile 文件本地路径（下载的文件，写到本地）
     * @param {}int $downloadFileType 合同文件类型（多附件下载 1：pdf文件, 2：多个单张png文件（含pdf文件，单附件对应单张图片）, 3：分页png压缩文件 （含pdf文件）, 4：合同单张图片（不含pdf文件）, 5：所有的分页图片（不含pdf文件））
     * @return {*}
     */
    public function downloadByAttachName($contractNo,$attachNames,$outfile,$downloadFileType){
        $this->url = '/contract/downloadByAttachName';
        $this->data = [
            'contractNo'       => $contractNo,
            'attachNames'      => $attachNames,
            'outfile'          => $outfile,
            'downloadFileType' => $downloadFileType,
        ];
        return $this->request();
    }
    /**
     * @author: Neupres·lin
     * @name: downloadChainReport
     * @description: 下载区块链存证报告
     * @param {*}String $contractNo 合同编号
     * @return {*}
     */
    public function downloadChainReport($contractNo){
        $this->url = '/contract/downloadChainReport';
        $this->data = [
            'contractNo' => $contractNo,
        ];
        return $this->request();
    }




    /**
     * @author: Neupres·lin
     * @name: faceCompare
     * @description: 人脸照片比对
     * @param {*}String $name 姓名
     * @param {*}String $idCard 身份证号码
     * @param {}String $url 照片地址（url 和 image 2个必选一个）
     * @param {}String $image base64的图片内容（url 和 image 2个必选一个）
     * @return {*}
     */
    public function faceCompare($name,$idCard,$url,$image){
        $this->url = '/user/faceCompare';
        $this->data = [
            'name'   => $name,
            'idCard' => $idCard,
            'url'    => $url,
            'image'  => $image,
        ];
        return $this->request();
    }
    /**
     * @author: Neupres·lin
     * @name: ocr
     * @description: ocr身份证识别
     * @param {*}MultipartFile $image 图片信息
     * @param {*}String $side front（正面）、back（反面）
     * @return {*}
     */
    public function templateUpload($image,$tNo){
        $this->url = '/template/upload';
        $this->data = [
            'templateIdent'  => $tNo,
        ];
        return $this->requestFile($image,"file");
    }

    /**
     * @author: Neupres·lin
     * @name: request
     * @description: api请求封装 函数步骤 对参数排序->生成签名->使用phpcurl发送带签名的请求->处理返回
     * @param {*}
     * @return {*}
     */
    protected function request() {
        // 去掉空值key
        ksort($this->data);
        $this->data = $this->filterEmpty($this->data);
        //对参数进行排序
        //$this->sortField();
        $this->data = json_encode($this->data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
//        echo PHP_EOL;
//        var_dump($this->data);
        $time    = $this->msectime() + 600 * 1000;
        $signStr = $this->data . md5($this->data) . $this->appId . $time;
        $sign    = $this->sign($signStr, $this->apiSecret);
        $headers    = [
            "sign:" . $sign,
            // "Content-Type:application/form-data;",
        ];

        $postFields = ['bizData' => $this->data, 'appId' => $this->appId, 'timestamp' => $time];
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $this->domian.$this->url);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $postFields);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);

        $resData = curl_exec($curl);
//        echo PHP_EOL .$resData;
        $resData = json_decode($resData, true);
        if (empty($resData) || $resData['code'] != '100000') {
            $res = [
                'rt'   => false,
                'data' => $resData,
            ];
        } else {
            $res = [
                'rt'   => true,
                'data' => $resData['data'],
            ];
        }
        return $res;
    }

    protected function sortField(){
        ksort($this->data);
        foreach ($this->data as $key => $item) {
            // 数组
            if (is_array($this->data[$key])){
                $arrItem = $this->data[$key];
                foreach ($arrItem as $k => $v) {
                    ksort($arrItem);
                    if(is_array($arrItem[$k]) && isset($arrItem[$k][0])){
//                    if(is_array($arrItem[$k])){
                        // 属性还是数组
                        foreach ($arrItem[$k] as $k1 => $v1) {
                            foreach ($arrItem[$k][$k1] as $k2 => $v2) {
                                $objArr = $arrItem[$k][$k1];
//                                if (!$objArr->$k2) {
//                                    unset($objArr->$k2);
//                                }
                            }
                        }
                    }else {
                        // 是对象
                        if (is_object($arrItem[$k])) {
                            //asort($arrItem[$k]);
                        } else {
//                            // 去除空值key
//                            if (!$arrItem[$k]) {
//                                unset($arrItem[$k]);
//                            }
                        }
                    }
                }
                $this->data[$key] = $arrItem;
            }else{
                if(!$this->data[$key]){
                    unset($this->data[$key]);
                }
            }
        }
    }

    /**
     * @author: Neupres·lin
     * @name: requestFile
     * @description: 带自定义pdf合同的请求 需要的参数有contractFiles路径 contractName pdf文件名
     * @param {*}
     * @return {*}
     */
    protected function requestFile($filePath, $paramkey) {
        ksort($this->data);
        // 去掉空值key
        $this->data = $this->filterEmpty($this->data);
        //对参数进行排序
//        $this->sortField();
        $this->data = json_encode($this->data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
//        var_dump($this->data);
        $time    = $this->msectime() + 600 * 1000;
        $signStr = $this->data . md5($this->data) . $this->appId . $time;
        $sign    = $this->sign($signStr, $this->apiSecret);
        $headers    = [
            "sign:" . $sign,
            "Content-Type:multipart/form-data;",
        ];

        if($filePath){
            $fileArr = new CURLFile(realpath($filePath),pathinfo($filePath)['extension'],basename($filePath));
        }else{
            $fileArr = '';
        }

        $postFields = ['bizData' => $this->data, 'appId' => $this->appId, 'timestamp' => $time, $paramkey => $fileArr];
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $this->domian.$this->url);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $postFields);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
//        // 生成分隔符
//        $delimiter = '-------------' . uniqid();
//
//        // 需要上传的文件数组
//        $fileFields = array(
//            'file' => array(
//                'name' => 'test',
//                'type' => "pdf",
//                'content' => file_get_contents($filePath)
//            ),
//        );
//
//        $data = '';
//        // 先将post的普通数据生成主体字符串
//        $postFields = ['bizData' => $this->data, 'appId' => $this->appId, 'timestamp' => $time];
//        foreach ($postFields as $name => $content) {
//            $data .= "--" . $delimiter . "\r\n";
//            $data .= 'Content-Disposition: form-data; name="' . $name . '"';
//            $data .= "\r\n\r\n" . $content . "\r\n";
//        }
//
//        // 将上传的文件生成主体字符串
//        foreach ($fileFields as $name => $file) {
//            $data .= "--" . $delimiter . "\r\n";
//            $data .= 'Content-Disposition: form-data; name="' . $paramkey . '"; filename="' . $file['name'] . "\" \r\n";
//            $data .= 'Content-Type: ' . $file['type'] . "\r\n\r\n";
//            $data .= $file['content'] . "\r\n";
//        }
//        // 主体结束的分隔符
//        $data .= "--" . $delimiter . "--";
//
//        $curl = curl_init();
//        curl_setopt($curl, CURLOPT_URL, $this->domian.$this->url);
//        curl_setopt($curl, CURLOPT_HEADER, 0);
//        curl_setopt($curl, CURLOPT_POST, 1);
//        curl_setopt($curl, CURLOPT_POSTFIELDS, $postFields);
//        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
//        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
//        curl_setopt($curl, CURLOPT_HTTPHEADER, array(
//                'Content-Type: multipart/form-data; boundary=' . $delimiter,
//                'Content-Length: ' . strlen($data).";sign" . $sign)
//        );

        $resData = curl_exec($curl);
//        echo PHP_EOL .$resData;
        $resData = json_decode($resData, true);
        if (empty($resData) || $resData['code'] != '100000') {
            $res = [
                'rt'   => false,
                'data' => $resData,
            ];
        } else {
            $res = [
                'rt'   => true,
                'data' => $resData['data'],
            ];
        }
        return $res;
    }

    /**
     * @author: Neupres·lin
     * @name: 工具箱
     * @description: 包含接口常用工具
     * @param {*}
     * @return {*}
     */
    //时间戳protected
    public function msectime() {
        list($msec, $sec) = explode(' ', microtime());
        $msectime = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
        return $msectime;
    }
    //ras非对称加密
    protected function sign($signString,$priKey) {
        $priKey    = "-----BEGIN PRIVATE KEY-----\n" .
            wordwrap($priKey, 64, "\n", true) .
            "\n-----END PRIVATE KEY-----";
        //var_dump(extension_loaded('openssl'));
        $privKeyId = openssl_pkey_get_private($priKey);
        $signature = '';
        openssl_sign($signString, $signature, $privKeyId);
        //openssl_free_key($privKeyId);
        //var_dump("------------".$privKeyId);
        return base64_encode($signature);
    }
    //ras验证
    protected function verify($data, $signString, $pubKey) {
        $pubKey = "-----BEGIN PUBLIC KEY-----\n" .
            wordwrap($pubKey, 64, "\n", true) .
            "\n-----END PUBLIC KEY-----";
        $pubKey = openssl_pkey_get_public($pubKey);
        $result = (bool)openssl_verify($data, base64_decode($signString), $pubKey);
        //openssl_free_key($pubKey);
        return $result;
    }
}
